﻿using System;
using Fetches.Fetch.Dto;
using Fetches.Fetch.Fetcher;
using Fetches.Fetch.PagePool.Consume;

namespace Fetches.Fetch.Factory
{
    /// <summary>
    /// 面向终端用户的爬取系统，包含三方面API：
    /// 采集入库、消费加工、进度的查看
    /// </summary>
    public interface IFetchFactory
    {
        #region 数据采集

        /// <summary>
        /// 开始按FetchOrder入库数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="order"></param>
        /// <returns></returns>
        FetchReceipt Fetch<T>(FetchOrder order) where T : AbstractFetcher;

        /// <summary>
        /// 开始按FetchOrder入库数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="order"></param>
        /// <returns></returns>
        FetchReceipt Fetch<T>(FetchOrder<T> order) where T : AbstractFetcher;

        /// <summary>
        /// 加速入库，实际就是增加Fetcher
        /// </summary>
        /// <param name="receipt"></param>
        /// <param name="fetchers2Hire">考虑目标站情况，不建议增加太多</param>
        void SpeedUpFetch(FetchReceipt receipt,int fetchers2Hire);

        /// <summary>
        /// 减速入库，实际就是从FetcherIds中随机挑选几个Fetcher停掉
        /// </summary>
        /// <param name="receipt"></param>
        /// <param name="fetchers2Dismiss">要免职的fetcher数量只能小于当前任务的现有fetcher总数</param>
        void SpeedDownFetch(FetchReceipt receipt,int fetchers2Dismiss);

        /// <summary>
        /// 停止爬取入库
        /// </summary>
        /// <param name="receipt"></param>
        void StopFetch(FetchReceipt receipt);

        /// <summary>
        /// 继续入库，针对StopFetch
        /// </summary>
        /// <param name="receipt"></param>
        void ContinueFetch(FetchReceipt receipt);

        #endregion

        #region 数据加工

        /// <summary>
        /// 指定Processor，由工厂内部调度Processor消费
        /// </summary>
        /// <param name="processOrder">处理单中有入库的回执信息</param>
        /// <returns></returns>
        ProcessReceipt Process(ProcessOrder processOrder);

        /// <summary>
        /// 按照kafka的思路，可以以偏移来反复消费PagePool
        /// Consume方法是本地消费，Process方法是交给远程服务器消费
        /// </summary>
        /// <param name="receipt"></param>
        /// <returns></returns>
        PagePoolConsumer Consume(FetchReceipt receipt);

        #endregion

        #region 进度监控

        /// <summary>
        /// 由Factory主动通知回调函数爬取进度
        /// </summary>
        /// <param name="receipt"></param>
        /// <param name="progressAction"></param>
        /// <returns></returns>
        void Watch(FetchReceipt receipt, Action<FetchTaskProgress> progressAction);


        #endregion
    }
}
